﻿/*
===========================================================================

  Copyright (c) 2010-2014 Darkstar Dev Teams

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program.  If not, see http://www.gnu.org/licenses/

  This file is part of DarkStar-server source code.

===========================================================================
*/

#ifndef _MOBENTITY_H
#define _MOBENTITY_H

#include "battleentity.h"
#include "../enmity_container.h"
#include "../utils/mobutils.h"
#include "../mob_modifier.h"

#include "../mob_spell_container.h"
#include "../mob_spell_list.h"

// Forward declaration
class CMobSpellContainer;

/************************************************************************
*                                                                       *
*  MobEntity DEFINEs.                                                   *
*  This will make mobs walk back to spawn point instead of despawning   *
*                                                                       *
************************************************************************/

#define MOB_NO_DESPAWN false
#define MOB_SOUND_RANGE 8
#define MOB_SIGHT_RANGE 15
#define MOB_LINK_RADIUS 10
#define MOB_TP_USE_CHANCE 30        // 30% chance to use TP if over 100

/************************************************************************
*                                                                       *
*  Spawn type enumeration.                                              *
*                                                                       *
************************************************************************/

enum SPAWNTYPE
{
    SPAWNTYPE_NORMAL        = 0x00, // 00:00-24:00
    SPAWNTYPE_ATNIGHT       = 0x01, // 20:00-04:00
    SPAWNTYPE_ATEVENING     = 0x02, // 18:00-06:00
    SPAWNTYPE_WEATHER       = 0x04, // Dependant on weather condition
    SPAWNTYPE_FOG           = 0x08, // 02:00-07:00
    SPAWNTYPE_MOONPHASE     = 0x10, // Dependant on Moon Phase
    SPAWNTYPE_LOTTERY       = 0x20, // Random lottery
    SPAWNTYPE_WINDOWED      = 0x40, // ​​I have no idea what it is ^ ^
    SPAWNTYPE_SCRIPTED      = 0x80  // Scripted spawn
};

/************************************************************************
*                                                                       *
*  Special Flag enumeration.                                            *
*                                                                       *
************************************************************************/

enum SPECIALFLAG
{
    SPECIALFLAG_NONE      = 0x0,
    SPECIALFLAG_HIDDEN    = 0x1  // only use special when hidden
};

/************************************************************************
*                                                                       *
*  Roaming flag enumeration.                                            *
*                                                                       *
************************************************************************/

enum ROAMFLAG : uint16
{
    ROAMFLAG_NONE     = 0x00,
    ROAMFLAG_SMALL    = 0x01,  // Move around less than 5
    ROAMFLAG_MEDIUM   = 0x02,  // Move around 10-20
    ROAMFLAG_LARGE    = 0x04,  // Move around 15-25
    ROAMFLAG_WANDER   = 0x08,  // Roam to multiple points in a row
    ROAMFLAG_SCOUT    = 0x10,  // Move around more often
    ROAMFLAG_GUARD    = 0x20,  // Move less often
    ROAMFLAG_WORM     = 0x40,  // Pop up and down when moving
    ROAMFLAG_AMBUSH   = 0x80,  // Stays hidden until someone comes close (antlion)
    ROAMFLAG_EVENT    = 0x100, // Calls lua method for roaming logic
    ROAMFLAG_IGNORE   = 0x200, // Ignore all hate, except linking hate
    ROAMFLAG_STEALTH  = 0x400  // stays name hidden and untargetable until someone comes close (chigoe)
};

/************************************************************************
*                                                                       *
*  Mob type enumeration.                                                *
*                                                                       *
************************************************************************/

enum MOBTYPE
{
    MOBTYPE_NORMAL      = 0x00, // Normal
    MOBTYPE_PCSPAWNED   = 0x01, // Forced Spawn
    MOBTYPE_NOTORIOUS   = 0x02, // Notorious Monster
    MOBTYPE_FISHED      = 0x04, // Fished up
    MOBTYPE_CALLED      = 0x08, // Scripted
    MOBTYPE_BATTLEFIELD = 0x10, // BCNM
    MOBTYPE_EVENT       = 0x20  // Special Event
};

/************************************************************************
*                                                                       *
*  Agro type enumeration.                                               *
*                                                                       *
************************************************************************/

enum AGGRO : uint16
{
	AGGRO_NONE					= 0x00,
	AGGRO_DETECT_SIGHT			= 0x01,
	AGGRO_DETECT_HEARING		= 0x02,
	AGGRO_DETECT_LOWHP			= 0x04,
	AGGRO_DETECT_TRUEHEARING	= 0x08,
	AGGRO_DETECT_TRUESIGHT		= 0x10,
	AGGRO_DETECT_MAGIC			= 0x20,
	AGGRO_DETECT_WEAPONSKILL	= 0x40,
	AGGRO_DETECT_JOBABILITY		= 0x80,
	AGGRO_SCENT					= 0x100
};

/************************************************************************
*                                                                       *
*  Behaviour type enumeration.                                          *
*                                                                       *
************************************************************************/

enum BEHAVIOUR : uint16
{
	BEHAVIOUR_NONE				= 0x000,
	BEHAVIOUR_NO_DESPAWN		= 0x001, // mob does not despawn on death
	BEHAVIOUR_STANDBACK			= 0x002, // mob will standback forever
	BEHAVIOUR_RAISABLE			= 0x004, // mob can be raised via Raise spells
	BEHAVIOUR_AGGRO_AMBUSH		= 0x200, // mob aggroes by ambush
	BEHAVIOUR_NO_TURN           = 0x400  // mob does not turn to face target
};


/************************************************************************
*                                                                       *
*  Battle Entities                                                      *
*                                                                       *
************************************************************************/

class CMobEntity : public CBattleEntity
{
public:

    bool      m_AllowRespawn;           // if true, allow respawn
    bool        m_ForceDespawn;
    uint32    m_RespawnTime;            // respawn time
    uint32    m_DropItemTime;           // time until monster death animation

    uint32    m_DropID;                 // dropid of items to be dropped. dropid in Database (mob_droplist)

    uint8       m_minLevel;             // Lowest possible level monster
    uint8       m_maxLevel;             // Maximum possible level monster
    uint32      HPmodifier;             // HP in Database (mob_groups)
    uint32      MPmodifier;             // MP in Database (mob_groups)

    float       HPscale;                // HP boost percentage
    float       MPscale;                // MP boost percentage

    uint16      m_roamFlags;            // Defines its roaming behaviour
    uint8       m_specialFlags;         // Flags for special skill

    bool        m_StatPoppedMobs;       // True if dyna statue has popped mobs

    // Stat ranks
    uint8       strRank;
    uint8       dexRank;
    uint8       vitRank;
    uint8       agiRank;
    uint8       intRank;
    uint8       mndRank;
    uint8       chrRank;
    uint8       attRank;
    uint8       defRank;
    uint8       accRank;
    uint8       evaRank;                // Not used

    uint16  m_dmgMult;

    // Aggro ranges
    bool        m_disableScent;         // Stop detecting by scent
    float       m_maxRoamDistance;      // Maximum distance mob can be from spawn

    uint8     m_Type;                   // mob type
    uint16    m_Aggro;					// mob aggro type
    uint8     m_Link;                   // link with mobs of it's family
    uint16    m_Behaviour;              // mob behaviour
    SPAWNTYPE m_SpawnType;              // condition for mob to spawn
    uint32    m_extraVar;               // extra variable to store combat related variables from scripts

    uint8     m_CallForHelp;            // call for help flag on mob

    int8      m_battlefieldID;          // Battlefield belonging to
    uint16    m_bcnmID;                 // Belongs to which battlefield
    bool      m_giveExp;                // Prevent exp gain
    bool      m_neutral;                // Stop linking / aggroing

    position_t    m_SpawnPoint;         // spawn point of mob

    uint8     m_Element;
    uint8     m_HiPCLvl;                // Highest Level of Player Character that hit the Monster
    uint8     m_THLvl;                  // Highest Level of Treasure Hunter that apply to drops
    bool      m_ItemStolen;             // If true, mob has already been robbed. reset on respawn. also used for thf maat fight
    uint16    m_Family;                 // Family of the mob
    uint32    m_Pool;                   // Pool the mob came from

    CMobSpellList*      m_SpellListContainer;          // The spells list container for this mob
    std::map<uint16, uint16>    m_UsedSkillIds;        // Mob skill ids used (key) along with mob level (value)

    uint32    m_unknown;                               // Includes the CFH flag and whether the HP bar should be shown or not (e.g. Yilgeban doesnt)
    uint8     m_name_prefix;                           // The ding bats VS Ding bats

    CEnmityContainer* PEnmityContainer;                // система ненависти монстров System hate monsters

    bool      hasRageMode();                           // If the mob has the rage mode: true
    void      addRageMode();                           // Rage mode ON:  stat x10
    void      delRageMode();                           // Rage mode OFF: stat /10

    bool      IsFarFromHome();                         // Check if mob is too far from spawn
    bool      CanBeNeutral();                          // Check if mob can have killing pause

    bool      CanDetectTarget(CBattleEntity* PTarget, bool forceSight = false); // Can I detect the target?

    void      SetMainSkin(uint32 mobid);               // Set base skin for the mob (if mob or player dieing)
    void      SetNewSkin(uint8 skinid);                // Set new skin for the mob
    uint32    GetSkinID();                             // Get the last skinid (0 for base skin)

    uint8     TPUseChance();                           // Return % chance to use TP move

    void      ChangeMJob(uint16 job);                  // This will change jobs and update traits, stats, spells

    bool      CanDeaggro();                            // Check if the mob can deaggro
    uint32    GetDespawnTimer();                       // Return the amount of time left before a mob despawns
    void      SetDespawnTimer(uint32 duration);        // Set the time for a mob to despawn
    uint32    GetRandomGil();                          // Returns a random amount of gil
    bool      CanRoamHome();                           // Is it possible for me to walk back?
    bool      CanRoam();                               // Check if mob can walk around

    bool      CanLink(position_t* pos, int16 superLink = 0);  // Check if mobs can link

    bool      CanDropGil();                            // Mob has gil to drop
    bool      CanMug();                                // Not every mob with gil can be mugged // TODO: implement

    CMobSpellContainer* SpellContainer;                // Retrieves spells for the mob
    uint8     m_HasSpellScript;                        // 1 if they have a spell script to use for working out what to cast.

    void      setMobMod(uint16 type, int16 value);     // Sets a modifier on a mob
    int16     getMobMod(uint16 type);                  // Get the mob modifier on a mob
    void      addMobMod(uint16 type, int16 value);     // Add a mob modifier on a mob
    void      defaultMobMod(uint16 type, int16 value); // Set value if value has not been already set
    void      resetMobMod(uint16 type);                // Resets mob mod to original value
    int32     getBigMobMod(uint16 type);               // Multiplies mod by 1000
    void      saveMobModifiers();                      // Save current state of modifiers
    void      restoreMobModifiers();                   // Restore to saved state

    void      HideModel(bool hide);                    // Hide / show model
    bool      IsModelHidden();                         // Checks if the mob is hidden

    CMobEntity();
    ~CMobEntity();

private:

    bool        m_RageMode;                            // Mode rage
    bool        m_NewSkin;                             // True if skin has changed
    uint32      m_SkinID;                              // Skin ID
    uint32      m_DespawnTimer;                        // Despawn Timer to despawn mob after set duration
    int16       m_mobModStat[MAX_MOBMODIFIER];         // Mob specific mods
    int16       m_mobModStatSave[MAX_MOBMODIFIER];     // Saved state
};

#endif
